package com.tengju.data.infrastructure.repository.meta;

import com.tengju.data.domain.model.analysis.Meta;
import com.tengju.data.domain.model.analysis.MetaHolder;
import com.tengju.data.infrastructure.repository.meta.convert.MetaConvert;
import com.tengju.data.infrastructure.repository.meta.dataobject.MetaDO;
import com.tengju.data.infrastructure.shared.InfraException;
import com.tengju.user.domain.shared.JsonUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.yaml.snakeyaml.Yaml;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.*;

/**
 * @author chenhang
 * @Date 2021/5/3
 */
@Service
@Slf4j
public class MetaHolderImpl implements MetaHolder, InitializingBean {

    @Value("${meta.path}")
    private String metaPath;

    private final Map<String,Map<String,Meta>> metaMap = new HashMap<>(16);

    @Override
    public Map<String,Meta> listMeta(String bizKey) {
        return metaMap.getOrDefault(bizKey, Collections.emptyMap());
    }

    @Override
    public void afterPropertiesSet() {
        Yaml yaml = new Yaml();
        Resource[] resources;
        try {
            ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
            resources = resolver.getResources(metaPath);

            if (resources.length == 0) {
                throw new InfraException("加载metas文件失败");
            }

            Map<String, Map<String, Object>> map = new HashMap<>(16);
            for (Resource resource : resources) {
                log.debug("resources:name:{}", resource.getFilename());
                if (StringUtils.isEmpty(resource.getFilename())) {
                    continue;
                }
                map.put(resource.getFilename().replace(".yaml",""),
                        yaml.loadAs(new BufferedReader(new InputStreamReader(resource.getInputStream())), Map.class));
            }
            Set<Map.Entry<String, Map<String, Object>>> set = map.entrySet();

            for (Map.Entry<String, Map<String, Object>> entry : set) {
                Map<String, Meta> bizMetaMap = new LinkedHashMap<>();
                Map<String, Object> metaValues = entry.getValue();
                if (CollectionUtils.isEmpty(metaValues)) {
                    continue;
                }
                for (Map.Entry<String, Object> valueEntry : metaValues.entrySet()) {
                    MetaDO metaDO = JsonUtil.toObject(JsonUtil.toJSONString(valueEntry.getValue()), MetaDO.class);
                    if (metaDO == null) {
                        continue;
                    }
                    metaDO.setColName(valueEntry.getKey());
                    bizMetaMap.put(valueEntry.getKey(), MetaConvert.toMeta(metaDO));
                }
                metaMap.put(entry.getKey(), bizMetaMap);
            }
            log.info("metas:size:{}", metaMap.size());
        } catch (Exception e) {
            log.error("", e);
            throw new InfraException("metas加载失败");
        }
    }
}
